// 版权所有2011 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// Package crypto收集公共加密常量。
package crypto

import (
	"hash"
	"io"
	"strconv"
)

// 哈希标识在另一个
// 包中实现的加密哈希函数。
type Hash uint

// HashFunc只返回h的值，以便Hash实现SignerOpts。
func (h Hash) HashFunc() Hash {
	return h
}

func (h Hash) String() string {
	switch h {
	case MD4:
		return "MD4"
	case MD5:
		return "MD5"
	case SHA1:
		return "SHA-1"
	case SHA224:
		return "SHA-224"
	case SHA256:
		return "SHA-256"
	case SHA384:
		return "SHA-384"
	case SHA512:
		return "SHA-512"
	case MD5SHA1:
		return "MD5+SHA1"
	case RIPEMD160:
		return "RIPEMD-160"
	case SHA3_224:
		return "SHA3-224"
	case SHA3_256:
		return "SHA3-256"
	case SHA3_384:
		return "SHA3-384"
	case SHA3_512:
		return "SHA3-512"
	case SHA512_224:
		return "SHA-512/224"
	case SHA512_256:
		return "SHA-512/256"
	case BLAKE2s_256:
		return "BLAKE2s-256"
	case BLAKE2b_256:
		return "BLAKE2b-256"
	case BLAKE2b_384:
		return "BLAKE2b-384"
	case BLAKE2b_512:
		return "BLAKE2b-512"
	default:
		return "unknown hash value " + strconv.Itoa(int(h))
	}
}

const (
	MD4         Hash = 1 + iota // 进口戈朗。org/x/crypto/md4 
	MD5                         // 导入crypto/md5 
	SHA1                        // 导入crypto/sha1 
	SHA224                      // 导入crypto/sha256 
	SHA256                      // 导入crypto/sha256 
	SHA384                      // 导入crypto/sha512 
	SHA512                      // 导入crypto/sha512 
	MD5SHA1                     // 未实现；MD5+SHA1用于TLS RSA 
	RIPEMD160                   // 导入golang。org/x/crypto/ripemd160 
	SHA3_224                    // 导入golang。org/x/crypto/sha3 
	SHA3_256                    // 导入golang。org/x/crypto/sha3 
	SHA3_384                    // 导入golang。org/x/crypto/sha3 
	SHA3_512                    // 导入golang。org/x/crypto/sha3 
	SHA512_224                  // 导入crypto/sha512 
	SHA512_256                  // 导入crypto/sha512 
	BLAKE2s_256                 // 导入golang。org/x/crypto/blake2s 
	BLAKE2b_256                 // 导入golang。org/x/crypto/blake2b 
	BLAKE2b_384                 // 导入golang。org/x/crypto/blake2b 
	BLAKE2b_512                 // 导入golang。org/x/crypto/blake2b 
	maxHash
)

var digestSizes = []uint8{
	MD4:         16,
	MD5:         16,
	SHA1:        20,
	SHA224:      28,
	SHA256:      32,
	SHA384:      48,
	SHA512:      64,
	SHA512_224:  28,
	SHA512_256:  32,
	SHA3_224:    28,
	SHA3_256:    32,
	SHA3_384:    48,
	SHA3_512:    64,
	MD5SHA1:     36,
	RIPEMD160:   20,
	BLAKE2s_256: 32,
	BLAKE2b_256: 32,
	BLAKE2b_384: 48,
	BLAKE2b_512: 64,
}

// Size返回给定哈希
// 函数产生的摘要的长度（字节）。它不需要将所讨论的哈希函数链接到程序中。
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

var hashes = make([]func() hash.Hash, maxHash)

// New返回一个新的哈希。哈希计算给定的哈希函数。如果哈希函数未链接到二进制文件中，则会产生新的恐慌
// 。
func (h Hash) New() hash.Hash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
}

// 可用报告给定的哈希函数是否链接到二进制文件中。
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash注册一个函数，该函数返回给定
// 哈希函数的新实例。这是从实现哈希函数的
// 包中的init函数调用的。
func RegisterHash(h Hash, f func() hash.Hash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}

// 公钥表示使用未指定算法的公钥。
// 
// 尽管出于向后兼容的原因，此类型是空接口，
// 标准库中的所有公钥类型都实现以下接口
// 
// 接口{
// Equal（x crypto.PublicKey）bool 
// }
// 
// 可用于提高应用程序中的类型安全性。
type PublicKey any

// PrivateKey表示使用未指定算法的私钥。
// 
// 尽管出于向后兼容的原因，此类型是空接口，
// 标准库中的所有私钥类型都实现以下接口
// 
// 接口{
// Public（）crypto.PublicKey 
// Equal（x crypto.PrivateKey）bool 
// 以及特定用途的接口，如签名者和Decrypter，
// 可用于提高应用程序中的类型安全性。
type PrivateKey any

// 签名者是一个不透明私钥的接口，可用于
// 签名操作。例如，保存在硬件模块中的RSA密钥。
type Signer interface {
	// Public返回与不透明的
	// 私钥对应的公钥。
	Public() PublicKey

	// 使用私钥签名摘要，可能使用
	// 兰德的熵。对于RSA密钥，生成的签名应该是
	// PKCS#1 v1。5或PSS签名（如opts所示）。对于一个（EC）DSA 
	// 密钥，它应该是一个序列化的DER，ASN。1.签名结构。
	// 
	// 哈希实现SignerOpts接口，在大多数情况下，只需传入用作OPT的哈希函数即可。Sign还可以尝试
	// 将assert opts类型设置为其他类型，以获得算法
	// 特定值。有关详细信息，请参阅每个软件包中的文档。
	// 
	// 注意，当需要对较大消息的哈希进行签名时，
	// 调用者负责对较大消息进行哈希，并将哈希（作为摘要）和哈希函数（作为选项）传递给签名者。
	Sign(rand io.Reader, digest []byte, opts SignerOpts) (signature []byte, err error)
}

// SignerOpts包含与签名者签名的选项。
type SignerOpts interface {
	// HashFunc返回用于生成传递给签名者的消息的hash函数的标识符。符号，否则为零表示未进行
	// 哈希运算。
	HashFunc() Hash
}

// Decrypter是不透明私钥的接口，可用于
// 非对称解密操作。例如，保存在硬件模块中的RSA密钥
// 就是一个例子。
type Decrypter interface {
	// Public返回与不透明的
	// 私钥对应的公钥。
	Public() PublicKey

	// 解密解密消息。opts参数应该适用于
	// 所使用的原语。有关
	// 详细信息，请参阅每个实现中的文档。
	Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error)
}

type DecrypterOpts any
